#ifndef __CAN_ALYST_II__
#define __CAN_ALYST_II__

#include <QMainWindow>
#include <QDebug>

#include "sys.h"
#include "ControlCAN.h"

namespace Ui
{
    class can_alyst_ii;
}

class can_alyst_ii : public QObject
{
    Q_OBJECT

public:
    can_alyst_ii(void);
    ~can_alyst_ii(void);

    /* 是否使用信号控制自动收发 */
    #define AUTO_RECEIVE_TRANSMIT_USE_SIGNALS    (flase)

    /* 自动收发定时器 */
    QTimer *auto_receive_timer;
    QTimer *auto_transmit_timer;

    /* ==== 参数枚举 ==== */

    /* 通道名称 */
    enum channel_e
    {
        ch_1 = 0,      /* 通道1 */
        ch_2 = 1,      /* 通道2 */

        ch_num = 2,    /* 通道数量 */
    };
    typedef enum channel_e channel_t;

    /* 滤波方式 */
    enum filter_e
    {
        filter_all = 0,         /* 接收所有帧 */
        filter_std_only = 2,    /* 只接收标准帧 */
        filter_ext_only = 3,    /* 只接收扩展帧 */
    };
    typedef enum filter_e filter_t;

    /* 工作模式 */
    enum work_mode_e
    {
        work_mode_normal = 0,      /* 正常工作 */
        work_mode_stlent = 1,      /* 监听模式 */
        work_mode_loop_bak = 2,    /* 自发自收 */
    };
    typedef enum work_mode_e work_mode_t;

    /* 发送类型 */
    enum send_type_e
    {
        send_normal = 0,    /* 正常发送 */
        send_once = 1,      /* 单次发送 */
    };
    typedef enum send_type_e send_type_t;

    /* 帧类型 */
    enum frame_type_e
    {
        frame_data = 0,      /* 数据帧 */
        frame_remote = 1,    /* 远程帧 */
    };
    typedef enum frame_type_e frame_type_t;

    /* CAN ID 类型 */
    enum id_type_e
    {
        id_std = 0,    /* 标准帧 ID = 11bit */
        id_ext = 1,    /* 扩展帧 ID = 29bit */
    };
    typedef enum id_type_e id_type_t;

    /* ==== 自动收发相关变量 ==== */

    #if AUTO_RECEIVE_TRANSMIT_USE_SIGNALS

        bool auto_receive_flag = false;
        bool auto_transmit_flag = false;

        uint auto_transmit_time = 500;
        uint auto_transmit_time_cnt = 0;

    #endif

    struct auto_transmit_s
    {
        channel_t ch = ch_1;
        uchar dat[8];
        uchar dat_len = 8;
    };
    typedef struct auto_transmit_s auto_transmit_t;
    auto_transmit_t auto_transmit_dat;

    /* ==== 设备参数变量 ==== */

    /* 设备类型 */
    ulong device_type;

    /* 设备索引 */
    ulong device_index;

    /* 通道索引 */
    ulong device_channel;

    /* ==== 板卡信息变量 ==== */

    /* 板卡信息 */
    VCI_BOARD_INFO vci_board_info;

    /* ==== 波特率字典 ==== */

    /* 波特率字典 */
    QMap<QString, uchar> baudrate_timing_0_map;
    QMap<QString, uchar> baudrate_timing_1_map;

    /* ==== 参数配置 ==== */

    struct parameter_config_s
    {
        /* ==== 发送相关 ==== */

        /* CAN ID */
        uint id;

        /* CAN ID 类型 */
        id_type_t id_type;

        /* 帧类型 */
        frame_type_t frame_type;

        /* 发送选项 */
        send_type_t send_type;

        /* ==== 初始相关 ==== */

        /* 工作模式 */
        work_mode_t mode;

        /* 波特率 */
        QString baudrate;

        /* 滤波方式 */
        filter_t filter;

        /* 验收码 */
        ulong acc_code;

        /* 屏蔽码 */
        ulong acc_mask;

    };
    typedef struct parameter_config_s parameter_config_t;
    parameter_config_t parameter_config[(int)ch_num];

    /* ==== 函数 ==== */

    /* 打开设备 */
    void open_device(void);

    /* 关闭设备 */
    void close_device(void);

    /* 读取板卡信息 */
    void read_board_info(void);

    /* 清空缓存 */
    void clear_buffer(channel_t ch_num);

    /* 初始化通道 */
    void channel_init(channel_t ch_num);

    /* 打开通道 */
    void channel_start(channel_t ch_num);

    /* 重启通道 */
    void channel_reset(channel_t ch_num);

    /* 发送数据 */
    void transmit(channel_t ch_num, uchar *msg, uchar data_len);

    /* 接收数据 */
    void receive(channel_t ch_num);

private:

private slots:

    /* 自动收发处理函数 */
    void auto_transmit(void);
    void auto_receive(void);

    #if !AUTO_RECEIVE_TRANSMIT_USE_SIGNALS

        /* 自动收发定时器控制函数 */
        void auto_receive_timer_ctrl(bool sw, int tim);
        void auto_transmit_timer_ctrl(bool sw, int tim);

    #endif

signals:

    /* 通道接收到消息信号 */
    void ch1_receive_msg_signals(VCI_CAN_OBJ *ch1_dat_buf, ulong ch1_dat_num);
    void ch2_receive_msg_signals(VCI_CAN_OBJ *ch2_dat_buf, ulong ch2_dat_num);

    #if !AUTO_RECEIVE_TRANSMIT_USE_SIGNALS

        /* 控制自动收发信号 */

        void auto_receive_ctrl_signals(bool sw, int tim);
        void auto_transmit_ctrl_signals(bool sw, int tim);

    #endif
};

#endif /* __CAN_ALYST_II__ */
